package dto

import (
	"fmt"
	"oss-api/app/model"
	"oss-api/boot"
	"oss-api/library/response"
	"strings"
	"time"
)

var Resource = new(ResourceDto)

type ResourceDto struct{}

// Count 统计某一条件查询数据
func (r *ResourceDto) Count(query interface{}, args ...interface{}) (int64, error) {
	var count int64
	tx := boot.DB.Model(&model.Resource{}).
		Where(query, args).
		Count(&count)
	if tx.Error != nil {
		return 0, tx.Error
	}
	return count, nil
}

func (r *ResourceDto) SelectPage(cateId int64, page, limit int) ([]response.ResourceVo, error) {
	var (
		data  []response.ResourceVo
		start int
		err   error
	)
	start = (page - 1) * limit
	err = boot.DB.Model(&model.Resource{}).
		Where("cate_id = ? and can_view = true", cateId).
		Order("create_time").
		Offset(start).
		Limit(limit).
		Find(&data).Error
	if err != nil {
		return nil, err
	}
	return data, nil

}

// CreateResource 创建记录
func (r *ResourceDto) CreateResource(cateId, size int64, path, fileName, url, tags string, brief string) (model.Resource, error) {
	split := strings.Split(fileName, ".")
	resource := model.Resource{
		Id:          boot.IdBuilder.NextId(),
		Title:       split[0],
		CateId:      cateId,
		HandleUrl:   url,
		OriginalUrl: url,
		Tags:        tags,
		Format:      split[1],
		FileSize:    size,
		AccessPerm:  true,
		CreateTime:  time.Now(),
		UpdateTime:  time.Now(),
		CanView:     true,
		Brief:       brief,
	}

	err := boot.DB.Save(&resource).Error
	if err != nil {
		return model.Resource{}, err
	}

	endpoint := boot.Config.Storage.Cloud.Endpoint
	resource.OriginalUrl = fmt.Sprintf("https://%s/%s", endpoint, resource.OriginalUrl)
	resource.HandleUrl = fmt.Sprintf("https://%s/%s", endpoint, resource.HandleUrl)

	return resource, nil

}

// DeleteResourceByIds 删除资源通过ids
func (r *ResourceDto) DeleteResourceByIds(ids []int64, flag bool) (bool, error) {
	err := boot.DB.
		Model(&model.Resource{}).
		Where("id in ?", ids).
		Updates(map[string]interface{}{"can_view": flag, "update_time": time.Now()}).
		Error
	if err != nil {
		return false, err
	}
	return true, nil
}

// SelectPageWithDelete 分页获取删除的资源
func (r *ResourceDto) SelectPageWithDelete(page, limit int, cateId int64, name string) ([]response.GarbagePageVo, int64, error) {
	var (
		condition map[string]interface{}
		count     int64
		data      []response.GarbagePageVo
		err       error
	)

	condition = make(map[string]interface{}, 0)
	condition["oss_resources.can_view"] = false
	if cateId != 0 {
		condition["oss_resources.cate_id"] = cateId
	}
	if name != "" {
		condition["oss_resources.title like %?%"] = name
	}

	err = boot.DB.Model(&model.Resource{}).
		Select("oss_resources.*, oss_categories.title as cate_name").
		Joins("left join oss_categories on oss_categories.id = oss_resources.cate_id").
		Where(condition).
		Limit(limit).
		Offset((page - 1) * limit).
		Find(&data).
		Error
	if err != nil {
		return nil, 0, err
	}
	err = boot.DB.Model(&model.Resource{}).
		Where(condition).
		Count(&count).
		Error

	if err != nil {
		return nil, 0, err
	}
	return data, count, nil
}

func (r *ResourceDto) FindAllStatusDelete(query interface{}, args ...interface{}) ([]model.Resource, error) {
	var result []model.Resource
	err := boot.DB.
		Model(&model.Resource{}).
		Where(query, args).
		Find(&result).
		Error
	if err != nil {
		return nil, err
	}
	return result, nil
}

// RealDelete 真正删除
func (r *ResourceDto) RealDelete(id ...int64) (bool, error) {
	err := boot.DB.Model(&model.Resource{}).Delete("id in (?)", id).Error
	if err != nil {
		return false, err
	}
	return true, nil
}

// SetResourceVisit 设置访问权限
func (r *ResourceDto) SetResourceVisit(id int64, state bool) (bool, error) {
	err := boot.DB.
		Model(&model.Resource{}).
		Where("id = ?", id).
		Updates(map[string]interface{}{"access_perm": state, "update_time": time.Now()}).
		Error
	if err != nil {
		return false, err
	}
	return true, nil
}

// FindOne 发现一条数据
func (r *ResourceDto) FindOne(query interface{}, args ...interface{}) (model.Resource, error) {
	var result model.Resource
	err := boot.DB.
		Model(&model.Resource{}).
		Where(query, args).
		Take(&result).
		Error
	if err != nil {
		return model.Resource{}, err
	}
	return result, nil
}

func (r *ResourceDto) FindTags() ([]string, error) {
	var data []string
	err := boot.DB.
		Raw("select distinct substring_index(tags, ',', -1) as tag  from oss_resources").
		Scan(&data).
		Error
	if err != nil {
		return []string{}, err
	}
	if len(data) == 0 {
		return []string{}, nil
	} else {
		return data, nil
	}

}
